package com.zhy.baselibrary.api

import com.blankj.utilcode.util.SPUtils
import com.google.gson.GsonBuilder
import com.google.gson.JsonDeserializer
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.sql.Timestamp
import java.util.concurrent.TimeUnit

class ApiFactory {
    private val retrofitMap = HashMap<String, Retrofit>()
    private var timeout = 60

    /**
     * 新增一个retrofit实例，可以通过[.create]或[.create]方法获取Api实现。<br></br>
     * key默认自增长。
     */
    fun add(baseUrl: String?) {
        retrofitMap[retrofitMap.size.toString() + ""] = createRetrofit(baseUrl)
    }

    /**
     * 新增一个retrofit实例，可以通过[.create]方法获取Api实现。<br></br>
     */
    fun add(key: String, baseUrl: String?) {
        retrofitMap[key] = createRetrofit(baseUrl)
    }

    /**
     * 获取Api实现，默认通第一个retrofit实例创建。
     */
    fun <T> create(clz: Class<T>?): T {
        checkRetrofitMap()
        return retrofitMap["0"]!!.create(clz)
    }

    /**
     * 根据key值获取Api实现
     */
    fun <T> create(key: Int, clz: Class<T>?): T {
        checkRetrofitMap()
        return retrofitMap[key.toString() + ""]!!.create(clz)
    }

    /**
     * 根据key值获取Api实现
     */
    fun <T> create(key: String, clz: Class<T>?): T {
        checkRetrofitMap()
        return retrofitMap[key]!!.create(clz)
    }

    /**
     * 设置OkHttp连接超时时间，默认30秒，请在[.add]或[.add]之前设置
     *
     * @param seconds 秒
     */
    fun setTimeout(seconds: Int) {
        timeout = seconds
    }

    private fun checkRetrofitMap() {
        check(retrofitMap.size > 0) { "Please add a Retrofit instance" }
    }

    private fun createRetrofit(baseUrl: String?): Retrofit {
        check(!(baseUrl == null || baseUrl.isEmpty())) { "BaseUrl cannot be null" }

        val builder = Retrofit.Builder()
        val gsonBuilder = GsonBuilder()
        gsonBuilder.registerTypeAdapter(
            Timestamp::class.java,
            JsonDeserializer { json, _, _ -> Timestamp(json.asJsonPrimitive.asLong) })

        builder.baseUrl(baseUrl)
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
        val okHttpBuilder = OkHttpClient.Builder()
        okHttpBuilder.readTimeout(timeout.toLong(), TimeUnit.SECONDS)
            .writeTimeout(timeout.toLong(), TimeUnit.SECONDS)
            .connectTimeout(timeout.toLong(), TimeUnit.SECONDS)

        okHttpBuilder.addInterceptor(Interceptor { chain ->
            val originalRequest = chain.request()
            val headers = originalRequest.headers()
            val builder1: Request.Builder = originalRequest.newBuilder()
            builder1.headers(headers)
            val token = SPUtils.getInstance().getString("token")
            if (token.isNotEmpty()) {
                builder1.addHeader("Authorization", token)
                chain.proceed(builder1.build())
            } else {
                chain.proceed(builder1.build())
            }
        })
        okHttpBuilder.addInterceptor(HttpLoggingInterceptor())
        builder.client(okHttpBuilder.build())
        return builder.build()
    }


    companion object {
        var factory: ApiFactory? = null
            get() {
                if (field == null) {
                    synchronized(ApiFactory::class.java) { if (field == null) field = ApiFactory() }
                }
                return field
            }
            private set
    }
}